package view;

import controller.ButtonActionListener;
import model.FileInformation;
import util.Config;
import util.TimeFormat;

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.util.*;

/**
 * PackageName: view
 * ClassName: MainView
 * Author: tum0r
 * Time: 2020/5/23 17:45
 */
public class MainView extends JFrame {
    // 主面板
    JPanel panel = new JPanel();

    // 输入输出文件夹
    private final JLabel IODirLabel = new JLabel();
    private final JTextField IODirPath = new JTextField();
    public final JButton IODirChoose = new JButton();
    private final JButton IODirCreateLabels = new JButton();

    // Labels.txt文件路径
    private final JLabel LabelsLabel = new JLabel();
    private final JTextField LabelsPath = new JTextField();
    private final JButton LabelsChoose = new JButton();
    private final JButton ResourceWrite = new JButton();

    // Resources.db文件路径
    private final JLabel ResourcesLabel = new JLabel();
    private final JTextField ResourcesPath = new JTextField();
    private final JButton ResourcesChoose = new JButton();
    private final JButton ResourcesCreate = new JButton();

    // 搜索
    private final JLabel SearchLabel = new JLabel();
    private final JTextArea SearchText = new JTextArea();
    private final JScrollPane SearchPane = new JScrollPane(SearchText);
    private final JButton Search = new JButton();

    // 文件提取和删除
    private final JLabel FileLabel = new JLabel();
    private final JTextArea FileID = new JTextArea();
    private final JScrollPane FilePane = new JScrollPane(FileID);
    private final JButton ExtractFile = new JButton();
    private final JButton DeleteFile = new JButton();

    // 搜索列表
    private final JTable SearchResult = new JTable(new Object[][]{}, Config.SEARCH_RESULT_HEADER);
    private final JScrollPane SearchResultPane = new JScrollPane(SearchResult);

    // 进度信息
    private final JLabel Progress = new JLabel();

    // 隔行颜色
    private final DefaultTableCellRenderer ROW_COLOR = new DefaultTableCellRenderer() {
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            if (row % 2 == 0) {
                setBackground(Config.SEARCH_RESULT_BACKGROUND_COLOR1);
                setForeground(Config.SEARCH_RESULT_FONT_COLOR1);
            } else if (row % 2 == 1) {
                setBackground(Config.SEARCH_RESULT_BACKGROUND_COLOR2);
                setForeground(Config.SEARCH_RESULT_FONT_COLOR2);
            }
            return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        }
    };

    // 控制器
    private ButtonActionListener buttonActionListener = new ButtonActionListener(this);

    public MainView() {
        initMainUI();
        initHeadUI();
        initBodyUI();
        initFootUI();
        addActionListener();
    }

    public void initMainUI() {
        setTitle(Config.MAIN_TITLE);
        setSize(Config.MAIN_SIZE.getWidth(), Config.MAIN_SIZE.getHeight());
        setLocationRelativeTo(Config.MAIN_LOCATION);
        setDefaultCloseOperation(Config.MAIN_CLOSE);
        setBackground(Config.MAIN_BACKGROUND_COLOR);
        setResizable(Config.MAIN_RESIZABLE);
        setLayout(Config.MAIN_LAYOUT);
        // FIXME macOS下不能修改
        setIconImage(Config.MAIN_ICON);
        SystemTray systemTray = SystemTray.getSystemTray();
        TrayIcon trayIcon = new TrayIcon(Config.MAIN_ICON);
        try {
            systemTray.add(trayIcon);
        } catch (AWTException e) {
            e.printStackTrace();
        }

        // TODO 主面板
        panel.setBounds(Config.MAIN_PANEL_SIZE.getX(), Config.MAIN_PANEL_SIZE.getY(), Config.MAIN_PANEL_SIZE.getWidth(), Config.MAIN_PANEL_SIZE.getHeight());
        panel.setBackground(Config.MAIN_PANEL_BACKGROUND);
        panel.setLayout(Config.MAIN_PANEL_LAYOUT);
        add(panel);
    }

    public void initHeadUI() {
        // TODO 输入输出文件夹
        IODirLabel.setBounds(Config.IO_DIR_LABEL_SIZE.getX(), Config.IO_DIR_LABEL_SIZE.getY(), Config.IO_DIR_LABEL_SIZE.getWidth(), Config.IO_DIR_LABEL_SIZE.getHeight());
        IODirLabel.setFont(Config.IO_DIR_LABEL_FONT);
        IODirLabel.setForeground(Config.IO_DIR_LABEL_FONT_COLOR);
        IODirLabel.setText(Config.IO_DIR_LABEL_TEXT);
        panel.add(IODirLabel);

        IODirPath.setBounds(Config.IO_DIR_PATH_SIZE.getX(), Config.IO_DIR_PATH_SIZE.getY(), Config.IO_DIR_PATH_SIZE.getWidth(), Config.IO_DIR_PATH_SIZE.getHeight());
        IODirPath.setFont(Config.IO_DIR_PATH_FONT);
        IODirPath.setForeground(Config.IO_DIR_PATH_FONT_COLOR);
        IODirPath.setBackground(Config.IO_DIR_PATH_BACKGROUND_COLOR);
        IODirPath.setText(Config.IO_DIR_PATH_TEXT);
        IODirPath.setHorizontalAlignment(Config.IO_DIR_PATH_TEXT_ALIGN);
        IODirPath.setEditable(Config.IO_DIR_PATH_EDITABLE);
        panel.add(IODirPath);

        IODirChoose.setBounds(Config.IO_DIR_CHOOSE_SIZE.getX(), Config.IO_DIR_CHOOSE_SIZE.getY(), Config.IO_DIR_CHOOSE_SIZE.getWidth(), Config.IO_DIR_CHOOSE_SIZE.getHeight());
        IODirChoose.setFont(Config.IO_DIR_CHOOSE_FONT);
        IODirChoose.setForeground(Config.IO_DIR_CHOOSE_FONT_COLOR);
        IODirChoose.setBorder(BorderFactory.createLineBorder(Config.IO_DIR_CHOOSE_BACKGROUND_COLOR, 2));
        IODirChoose.setText(Config.IO_DIR_CHOOSE_TEXT);
        panel.add(IODirChoose);

        IODirCreateLabels.setBounds(Config.IO_DIR_CREATE_LABELS_SIZE.getX(), Config.IO_DIR_CREATE_LABELS_SIZE.getY(), Config.IO_DIR_CREATE_LABELS_SIZE.getWidth(), Config.IO_DIR_CREATE_LABELS_SIZE.getHeight());
        IODirCreateLabels.setFont(Config.IO_DIR_CREATE_LABELS_FONT);
        IODirCreateLabels.setForeground(Config.IO_DIR_CREATE_LABELS_FONT_COLOR);
        IODirCreateLabels.setBorder(BorderFactory.createLineBorder(Config.IO_DIR_CREATE_LABELS_BACKGROUND_COLOR, 2));
        IODirCreateLabels.setText(Config.IO_DIR_CREATE_LABELS_TEXT);
        panel.add(IODirCreateLabels);

        // TODO Labels.txt文件路径
        LabelsLabel.setBounds(Config.LABELS_LABEL_SIZE.getX(), Config.LABELS_LABEL_SIZE.getY(), Config.LABELS_LABEL_SIZE.getWidth(), Config.LABELS_LABEL_SIZE.getHeight());
        LabelsLabel.setFont(Config.LABELS_LABEL_FONT);
        LabelsLabel.setForeground(Config.LABELS_LABEL_FONT_COLOR);
        LabelsLabel.setText(Config.LABELS_LABEL_TEXT);
        panel.add(LabelsLabel);

        LabelsPath.setBounds(Config.LABELS_PATH_SIZE.getX(), Config.LABELS_PATH_SIZE.getY(), Config.LABELS_PATH_SIZE.getWidth(), Config.LABELS_PATH_SIZE.getHeight());
        LabelsPath.setFont(Config.LABELS_PATH_FONT);
        LabelsPath.setForeground(Config.LABELS_PATH_FONT_COLOR);
        LabelsPath.setBackground(Config.LABELS_PATH_BACKGROUND_COLOR);
        LabelsPath.setText(Config.LABELS_PATH_TEXT);
        LabelsPath.setHorizontalAlignment(Config.LABELS_PATH_TEXT_ALIGN);
        LabelsPath.setEditable(Config.LABELS_PATH_EDITABLE);
        panel.add(LabelsPath);

        LabelsChoose.setBounds(Config.LABELS_CHOOSE_SIZE.getX(), Config.LABELS_CHOOSE_SIZE.getY(), Config.LABELS_CHOOSE_SIZE.getWidth(), Config.LABELS_CHOOSE_SIZE.getHeight());
        LabelsChoose.setFont(Config.LABELS_CHOOSE_FONT);
        LabelsChoose.setForeground(Config.LABELS_CHOOSE_FONT_COLOR);
        LabelsChoose.setBorder(BorderFactory.createLineBorder(Config.IO_DIR_CHOOSE_BACKGROUND_COLOR, 2));
        LabelsChoose.setText(Config.LABELS_CHOOSE_TEXT);
        panel.add(LabelsChoose);

        ResourceWrite.setBounds(Config.RESOURCE_WRITE_SIZE.getX(), Config.RESOURCE_WRITE_SIZE.getY(), Config.RESOURCE_WRITE_SIZE.getWidth(), Config.RESOURCE_WRITE_SIZE.getHeight());
        ResourceWrite.setFont(Config.RESOURCE_WRITE_FONT);
        ResourceWrite.setForeground(Config.RESOURCE_WRITE_FONT_COLOR);
        ResourceWrite.setBorder(BorderFactory.createLineBorder(Config.IO_DIR_CHOOSE_BACKGROUND_COLOR, 2));
        ResourceWrite.setText(Config.RESOURCE_WRITE_TEXT);
        panel.add(ResourceWrite);

        // TODO Resources.db文件路径
        ResourcesLabel.setBounds(Config.RESOURCES_LABEL_SIZE.getX(), Config.RESOURCES_LABEL_SIZE.getY(), Config.RESOURCES_LABEL_SIZE.getWidth(), Config.RESOURCES_LABEL_SIZE.getHeight());
        ResourcesLabel.setFont(Config.RESOURCES_LABEL_FONT);
        ResourcesLabel.setForeground(Config.RESOURCES_LABEL_FONT_COLOR);
        ResourcesLabel.setText(Config.RESOURCES_LABEL_TEXT);
        panel.add(ResourcesLabel);

        ResourcesPath.setBounds(Config.RESOURCES_PATH_SIZE.getX(), Config.RESOURCES_PATH_SIZE.getY(), Config.RESOURCES_PATH_SIZE.getWidth(), Config.RESOURCES_PATH_SIZE.getHeight());
        ResourcesPath.setFont(Config.RESOURCES_PATH_FONT);
        ResourcesPath.setForeground(Config.RESOURCES_PATH_FONT_COLOR);
        ResourcesPath.setBackground(Config.RESOURCES_PATH_BACKGROUND_COLOR);
        ResourcesPath.setText(Config.RESOURCES_PATH_TEXT);
        ResourcesPath.setHorizontalAlignment(Config.RESOURCES_PATH_TEXT_ALIGN);
        ResourcesPath.setEditable(Config.RESOURCES_PATH_EDITABLE);
        panel.add(ResourcesPath);

        ResourcesChoose.setBounds(Config.RESOURCES_CHOOSE_SIZE.getX(), Config.RESOURCES_CHOOSE_SIZE.getY(), Config.RESOURCES_CHOOSE_SIZE.getWidth(), Config.RESOURCES_CHOOSE_SIZE.getHeight());
        ResourcesChoose.setFont(Config.RESOURCES_CHOOSE_FONT);
        ResourcesChoose.setForeground(Config.RESOURCES_CHOOSE_FONT_COLOR);
        ResourcesChoose.setBorder(BorderFactory.createLineBorder(Config.RESOURCES_CHOOSE_BACKGROUND_COLOR, 2));
        ResourcesChoose.setText(Config.RESOURCES_CHOOSE_TEXT);
        panel.add(ResourcesChoose);

        ResourcesCreate.setBounds(Config.RESOURCES_CREATE_DATABASE_SIZE.getX(), Config.RESOURCES_CREATE_DATABASE_SIZE.getY(), Config.RESOURCES_CREATE_DATABASE_SIZE.getWidth(), Config.RESOURCES_CREATE_DATABASE_SIZE.getHeight());
        ResourcesCreate.setFont(Config.RESOURCES_CREATE_DATABASE_FONT);
        ResourcesCreate.setForeground(Config.RESOURCES_CREATE_DATABASE_FONT_COLOR);
        ResourcesCreate.setBorder(BorderFactory.createLineBorder(Config.RESOURCES_CREATE_DATABASE_BACKGROUND_COLOR, 2));
        ResourcesCreate.setText(Config.RESOURCES_CREATE_DATABASE_TEXT);
        panel.add(ResourcesCreate);
    }

    public void initBodyUI() {
        // TODO 搜索
        SearchLabel.setBounds(Config.SEARCH_LABEL_SIZE.getX(), Config.SEARCH_LABEL_SIZE.getY(), Config.SEARCH_LABEL_SIZE.getWidth(), Config.SEARCH_LABEL_SIZE.getHeight());
        SearchLabel.setFont(Config.SEARCH_LABEL_FONT);
        SearchLabel.setForeground(Config.SEARCH_LABEL_FONT_COLOR);
        SearchLabel.setText(Config.SEARCH_LABEL_TEXT);
        panel.add(SearchLabel);

        SearchText.setBounds(Config.SEARCH_TEXT_SIZE.getX(), Config.SEARCH_TEXT_SIZE.getY(), Config.SEARCH_TEXT_SIZE.getWidth(), Config.SEARCH_TEXT_SIZE.getHeight());
        SearchText.setFont(Config.SEARCH_TEXt_FONT);
        SearchText.setForeground(Config.SEARCH_TEXT_FONT_COLOR);
        SearchText.setBackground(Config.SEARCH_TEXT_BACKGROUND_COLOR);

        SearchPane.setBounds(Config.SEARCH_PANE_SIZE.getX(), Config.SEARCH_PANE_SIZE.getY(), Config.SEARCH_PANE_SIZE.getWidth(), Config.SEARCH_PANE_SIZE.getHeight());
        SearchPane.setBackground(Config.SEARCH_TEXT_BACKGROUND_COLOR);
        SearchPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        SearchPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        panel.add(SearchPane);

        Search.setBounds(Config.SEARCH_SIZE.getX(), Config.SEARCH_SIZE.getY(), Config.SEARCH_SIZE.getWidth(), Config.SEARCH_SIZE.getHeight());
        Search.setFont(Config.SEARCH_FONT);
        Search.setForeground(Config.SEARCH_FONT_COLOR);
        Search.setBorder(BorderFactory.createLineBorder(Config.SEARCH_BACKGROUND_COLOR, 2));
        Search.setText(Config.SEARCH_TEXT);
        panel.add(Search);

        // TODO 文件提取和删除
        FileLabel.setBounds(Config.FILE_LABEL_SIZE.getX(), Config.FILE_LABEL_SIZE.getY(), Config.FILE_LABEL_SIZE.getWidth(), Config.FILE_LABEL_SIZE.getHeight());
        FileLabel.setFont(Config.FILE_LABEL_FONT);
        FileLabel.setForeground(Config.FILE_LABEL_FONT_COLOR);
        FileLabel.setText(Config.FILE_LABEL_TEXT);
        panel.add(FileLabel);

        FileID.setBounds(Config.FILE_TEXT_SIZE.getX(), Config.FILE_TEXT_SIZE.getY(), Config.FILE_TEXT_SIZE.getWidth(), Config.FILE_TEXT_SIZE.getHeight());
        FileID.setFont(Config.FILE_TEXt_FONT);
        FileID.setForeground(Config.FILE_TEXT_FONT_COLOR);
        FileID.setBackground(Config.FILE_TEXT_BACKGROUND_COLOR);

        FilePane.setBounds(Config.FILE_PANE_SIZE.getX(), Config.FILE_PANE_SIZE.getY(), Config.FILE_PANE_SIZE.getWidth(), Config.FILE_PANE_SIZE.getHeight());
        FilePane.setBackground(Config.FILE_TEXT_BACKGROUND_COLOR);
        FilePane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        FilePane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        panel.add(FilePane);

        ExtractFile.setBounds(Config.EXTRACT_SIZE.getX(), Config.EXTRACT_SIZE.getY(), Config.EXTRACT_SIZE.getWidth(), Config.EXTRACT_SIZE.getHeight());
        ExtractFile.setFont(Config.EXTRACT_FONT);
        ExtractFile.setForeground(Config.EXTRACT_FONT_COLOR);
        ExtractFile.setBorder(BorderFactory.createLineBorder(Config.EXTRACT_BACKGROUND_COLOR, 2));
        ExtractFile.setText(Config.EXTRACT_TEXT);
        panel.add(ExtractFile);

        DeleteFile.setBounds(Config.DELETE_SIZE.getX(), Config.DELETE_SIZE.getY(), Config.DELETE_SIZE.getWidth(), Config.DELETE_SIZE.getHeight());
        DeleteFile.setFont(Config.DELETE_FONT);
        DeleteFile.setForeground(Config.DELETE_FONT_COLOR);
        DeleteFile.setBorder(BorderFactory.createLineBorder(Config.DELETE_BACKGROUND_COLOR, 2));
        DeleteFile.setText(Config.DELETE_TEXT);
        panel.add(DeleteFile);
    }

    public void initFootUI() {
        // TODO 搜索结果
        DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer();
        cellRenderer.setHorizontalAlignment(SwingConstants.CENTER);
        SearchResult.setBounds(Config.SEARCH_RESULT_SIZE.getX(), Config.SEARCH_RESULT_SIZE.getY(), Config.SEARCH_RESULT_SIZE.getWidth(), Config.SEARCH_RESULT_SIZE.getHeight());
        SearchResult.setFont(Config.SEARCH_RESULT_FONT);
        SearchResult.setBackground(Config.SEARCH_RESULT_BODY_BACKGROUND);
        SearchResult.setShowGrid(true);
        SearchResult.setShowHorizontalLines(true);
        SearchResult.setShowVerticalLines(true);
        SearchResult.setGridColor(Config.SEARCH_RESULT_GRID_COLOR);
        SearchResult.setDefaultRenderer(Object.class, cellRenderer);
        SearchResult.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        SearchResult.setSelectionBackground(Config.SEARCH_RESULT_SELECTED_BACKGROUND_COLOR);
        SearchResult.setSelectionForeground(Config.SEARCH_RESULT_SELECTED_FONT_COLOR);
        JTableHeader header = SearchResult.getTableHeader();
        header.setPreferredSize(Config.SEARCH_RESULT_HEAD_SIZE);
        header.setFont(Config.SEARCH_RESULT_HEAD_FONT);
        header.setBackground(Config.SEARCH_RESULT_HEAD_BACKGROUND_COLOR);
        header.setForeground(Config.SEARCH_RESULT_HEAD_FONT_COLOR);

        SearchResultPane.setBounds(Config.SEARCH_RESULT_PANE_SIZE.getX(), Config.SEARCH_RESULT_PANE_SIZE.getY(), Config.SEARCH_RESULT_PANE_SIZE.getWidth(), Config.SEARCH_RESULT_PANE_SIZE.getHeight());
        SearchResultPane.setBackground(Config.SEARCH_RESULT_PANE_BODY_BACKGROUND);
        SearchResultPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        SearchResultPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        panel.add(SearchResultPane);

        // TODO 进度信息
        Progress.setBounds(Config.PROGRESS_LABEL_SIZE.getX(), Config.PROGRESS_LABEL_SIZE.getY(), Config.PROGRESS_LABEL_SIZE.getWidth(), Config.PROGRESS_LABEL_SIZE.getHeight());
        Progress.setFont(Config.PROGRESS_LABEL_FONT);
        Progress.setForeground(Config.PROGRESS_LABEL_FONT_COLOR_NORMAL);
        setProgress(null, Config.PROGRESS_LABEL_TEXT);
        panel.add(Progress);
    }

    public void addActionListener() {
        IODirChoose.addActionListener(buttonActionListener);
        IODirCreateLabels.addActionListener(buttonActionListener);
        LabelsChoose.addActionListener(buttonActionListener);
        ResourceWrite.addActionListener(buttonActionListener);
        ResourcesChoose.addActionListener(buttonActionListener);
        ResourcesCreate.addActionListener(buttonActionListener);
        Search.addActionListener(buttonActionListener);
        ExtractFile.addActionListener(buttonActionListener);
        DeleteFile.addActionListener(buttonActionListener);
    }

    public void setIODirPath(String path) {
        IODirPath.setText(Objects.requireNonNullElseGet(path, String::new));
    }

    public String getIODirPath() {
        return IODirPath.getText().replace(Config.IO_DIR_PATH_TEXT, "");
    }

    public void setLabelsPath(String path) {
        LabelsPath.setText(Objects.requireNonNullElseGet(path, String::new));
    }

    public String getLabelsPath() {
        return LabelsPath.getText().replace(Config.LABELS_PATH_TEXT, "");
    }

    public void setResourcesPath(String path) {
        ResourcesPath.setText(Objects.requireNonNullElseGet(path, String::new));
    }

    public String getResourcesPath() {
        return ResourcesPath.getText().replace(Config.RESOURCES_PATH_TEXT, "");
    }

    private LinkedList<String> getText(String text) {
        LinkedList<String> result = new LinkedList<>();
        if (text != null && text.length() != 0) {
            String[] split = text.split("\n");
            for (String s : split) {
                if (s != null && s.trim().length() != 0 && s.replace("^", "").length() != 0) {
                    result.add(s.trim());
                }
            }
        }
        return result;
    }

    public String[] getSearchText() {
        String[] result = null;
        LinkedList<String> temp = getText(SearchText.getText().trim());
        if (temp.size() != 0) {
            result = temp.toArray(new String[0]);
        }
        return result;
    }

    public String[] getFileID() {
        String[] result = null;
        LinkedList<String> temp = getText(FileID.getText().trim());
        if (temp.size() != 0) {
            result = temp.toArray(new String[0]);
        }
        return result;
    }

    public void setSearchResult(LinkedList<FileInformation> files) {
        DefaultTableModel model = new DefaultTableModel(new Object[][]{}, Config.SEARCH_RESULT_HEADER);
        while (model.getRowCount() != 0) {
            model.removeRow(0);
        }
        for (FileInformation item : files) {
            model.addRow(new Object[]{item.getUUID(), item.getName(), item.getType(), item.getLabel(), item.getSize() + " " + item.getUnit(), TimeFormat.format(item.getCreateTime())});
        }
        int rowCount = model.getRowCount();
        if (rowCount > 0) {
            SearchResultPane.setBounds(Config.SEARCH_RESULT_PANE_SIZE.getX(), Config.SEARCH_RESULT_PANE_SIZE.getY(), Config.SEARCH_RESULT_PANE_SIZE.getWidth(), 40 * (Math.min(rowCount, 10) + 1) + 4);
            SearchResult.setModel(model);
            for (int i = 0; i < SearchResult.getColumnCount(); i++) {
                SearchResult.getColumn(SearchResult.getColumnName(i)).setCellRenderer(ROW_COLOR);
            }
            SearchResult.setRowHeight((int) Config.SEARCH_RESULT_CELL_SIZE.getHeight());
        }
    }

    public void setProgress(Color color, String text, Object... param) {
        color = color == null ? Config.PROGRESS_LABEL_FONT_COLOR_NORMAL : color;
        Progress.setForeground(color);
        if (param != null && param.length != 0) {
            Progress.setText("[" + TimeFormat.format(new Date()) + "] " + String.format(text, param));
        } else {
            Progress.setText("[" + TimeFormat.format(new Date()) + "] " + text);
        }
    }
}
